package com.niit.mall.product.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.niit.mall.api.domain.dto.OrderDetailDTO;
import com.niit.mall.common.api.CommonResult;
import com.niit.mall.common.domain.dto.PageDTO;
import com.niit.mall.common.utils.BeanUtils;
import com.niit.mall.product.domain.dto.ProductDTO;
import com.niit.mall.product.domain.dto.StockDTO;
import com.niit.mall.product.domain.po.Category;
import com.niit.mall.product.domain.po.Product;
import com.niit.mall.product.domain.query.ProductQuery;
import com.niit.mall.product.domain.query.ProductSearch;
import com.niit.mall.product.domain.vo.BrandVO;
import com.niit.mall.product.domain.vo.CategoryVO;
import com.niit.mall.product.domain.vo.ProductSynthesisVO;
import com.niit.mall.product.domain.vo.ProductVO;
import com.niit.mall.product.mapper.ProductMapper;
import com.niit.mall.product.service.ICategoryService;
import com.niit.mall.product.service.IProductService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author ChuXuan
 * @since 2025-05-26
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {

	private final ICategoryService categoryService;
	private final BrandServiceImpl brandService;
	private final ProductMapper productMapper;

	/**
	 * 获取商品分页和品牌、分类列表
	 * @return 商品分页和品牌、分类列表
	 */
	@Override
	public ProductSynthesisVO queryProductAndBrandAndCategoryList(ProductQuery query) {
		// 获取商品分页
		PageDTO<ProductDTO> productVOPageDTO = queryProductByPage(query);
		// 获取分类列表
		// List<CategoryVO> categoryVOList = categoryService.queryCategoryVO();
		List<Category> categoryList = categoryService.list();
		// 获取品牌列表
		List<BrandVO> brandVOList = brandService.queryBrandVO();
		// 封装数据
		return new ProductSynthesisVO(productVOPageDTO, brandVOList, categoryList);
	}

	/**
	 * 根据分页查询条件查询产品信息。
	 *
	 * @param query 查询条件
	 * @return 分页后的产品视图对象集合
	 */
	@Override
	public PageDTO<ProductDTO> queryProductByPage(ProductQuery query) {

		// 获取查询参数
		Integer publishStatus = query.getPublishStatus();
		Integer verifyStatus = query.getVerifyStatus();
		String keyword = query.getKeyword();
		String productSn = query.getProductSn();
		Long productCategoryId = query.getProductCategoryId();
		Long brandId = query.getBrandId();
		Integer minPrice = query.getMinPrice();
		Integer maxPrice = query.getMaxPrice();
		String sortBy = query.getSortBy();
		Boolean isAsc = query.getIsAsc();

		// 分页条件
		Page<Product> page = query.toMpPage(sortBy, isAsc);;

		// 执行查询
		Page<Product> productList = lambdaQuery()
				.eq(publishStatus != null, Product::getPublishStatus, publishStatus)
				.eq(verifyStatus != null, Product::getVerifyStatus, verifyStatus)
				.like(keyword != null, Product::getName, keyword)
				.eq(StringUtils.hasText(productSn), Product::getProductSn, productSn)
				.eq(productCategoryId != null, Product::getCategoryId, productCategoryId)
				.eq(brandId != null, Product::getBrandId, brandId)
				.gt(minPrice != null, Product::getPrice, minPrice)
				.lt(maxPrice != null, Product::getPrice, maxPrice)
				.page(page);

		return PageDTO.of(productList,  ProductDTO.class);
	}

	@Override
	public PageDTO<ProductVO> searchProductByPage(ProductSearch query) {
		// 获取查询参数
		String keyword = query.getKeyword();

		// 父分类id
		Integer categoryId = query.getCategoryId();
//		获取子分类idList
		List<Long> subCategoryIdList = categoryService.lambdaQuery()
				.eq(Category::getParentId, categoryId)
				.select(Category::getId)
				.list()
				.stream()
				.map(Category::getId)
				.collect(Collectors.toList());
		
		String type = query.getType();
		String sortBy;
		Boolean isAsc = null;

		if("default".equals(type)){
			sortBy = "id";
		}
		else if("price_asc".equals(type)){
			sortBy = "price";
			isAsc = true;
		}
		else if("price_desc".equals(type)){
			sortBy = "price";
			isAsc = false;
		}
		else if("sales".equals(type)){
			sortBy = "sold";
			isAsc = false;
		}
		else{
			sortBy = "id";
		}


		// 分页条件
		Page<Product> page = query.toMpPage(sortBy, isAsc);
		// 演示用 admin 查询所有
		if("admin".equals(keyword)){
			return PageDTO.of(productMapper.selectPage(page, new QueryWrapper<>()), ProductVO.class);
		}
		// 执行查询
		Page<Product> productList = lambdaQuery()
				.like(keyword != null, Product::getName, keyword)
				.in(!subCategoryIdList.isEmpty(), Product::getCategoryId, subCategoryIdList)
				.page(page);
		// 封装数据
		return PageDTO.of(productList, ProductVO.class);
	}

	/**
	 * 更新库存方法
	 *
	 * @param stockDTO 库存数据传输对象，包含产品ID和数量等信息
	 * @return 更新结果，成功返回true，失败返回false，当前默认实现返回false
	 * @Transactional 方法具有事务性，确保操作的原子性
	 */
	@Override
	@Transactional
	public boolean updateStock(StockDTO stockDTO) {
		Long productId = stockDTO.getProductId();
		Integer number = stockDTO.getNumber();
		Integer flag = stockDTO.getFlag();
		// TODO 更新库存
		return false;
		
	}

	@Override
	public void addProduct(ProductDTO productDTO) {
		productDTO.setCreateDate(LocalDate.now());
		productDTO.setUpdateDate(LocalDate.now());
		productMapper.addProduct(productDTO);
	}

	/**
	 * 根据ID列表查询商品信息
	 *
	 * @param ids 商品ID列表
	 * @return 查询到的商品数据传输对象列表
	 */
	@Override
	public List<ProductDTO> queryItemByIds(List<Long> ids) {
		// TODO
		return null;
	}

	/**
	 * 扣减库存方法
	 *
	 * @param items 订单详情数据传输对象列表
	 */
	@Override
	public void deductStock(List<OrderDetailDTO> items) {
		// TODO
	}

	/**
	 * 查询商品信息VO(包括逻辑删除的商品)
	 * @param id 商品ID
	 * @return 商品信息VO
	 */
	@Override
	public ProductDTO queryByIdLogic(Long id) {
		return BeanUtils.copyBean(productMapper.queryByIdLogic(id), ProductDTO.class);
	}



	@Override
	public Map<String, List<String>> querySpecsById(Long id) {
		Product product = baseMapper.selectById(id);
		return product.getSpecs();
	}

	@Override
	public void reduceStock(Map<Long, Integer> productIdToQuantityMap) {
		log.info("reduceStock: {}", productIdToQuantityMap);
		List<Product> productList = this.list(new LambdaQueryWrapper<Product>()
				.in(Product::getId, productIdToQuantityMap.keySet()));
		for (Product product : productList) {
			Integer quantity = productIdToQuantityMap.get(product.getId());
			if (quantity > product.getStock()) {
				throw new IllegalArgumentException("库存不足");
			}
			product.setStock(product.getStock() - quantity);
			this.updateById(product);
		}
	}
}
